#include "main.h"


extern SDL_Event event;

extern SDL_Rect camera;

//The surfaces
extern SDL_Surface *screen;
extern SDL_Surface *enemy;

//Player sprite from character sprite sheet
extern SDL_Rect clipsRight[ PLAYER_ANIMATIONS ];
extern SDL_Rect clipsLeft[ PLAYER_ANIMATIONS ];
extern SDL_Rect clipsUp[ PLAYER_ANIMATIONS ];
extern SDL_Rect clipsDown[ PLAYER_ANIMATIONS ];

//Constants specific to the enemy
const int FOUND = 1, NOT_FOUND = 0;

Enemy::Enemy()
{
    //Initialize the offsets
    box.x = ENEMY_X_POS;
    box.y = ENEMY_Y_POS;
    box.w = PLAYER_WIDTH;
    box.h = PLAYER_HEIGHT;

    //Initialize the velocity
    xVel = 0;
    yVel = 0;
    
    //Initialize the animation variables
    frame = 0;
    status = PLAYER_UP;
    
    bumped = false;
    lastAction = 0;
}

/*int Enemy::find_path( Tile *tiles[], SDL_Rect playerBox )
{
     //start tile
     Tile *startTile = tiles[ index_of_tileXY( box.x, box.y ) ];
     Tile *endTile = tiles[ index_of_tileXY( playerBox.x, playerBox.y ) ]; 
     
     //checks if no need to generate path
     if (startTile == endTile)
        return FOUND;
     
     queue<Tile*> openList;
     vector<Tile*> visited;
     
     startTile->set_parent( NULL );
     openList.push( startTile );
     
     while ( !openList.empty() )
     {
           //get the lowest F cost square on the open list.
           //we refer to this as the current square.
           Tile *currSquare = openList.front();
           
           //switch the currentSquare to the closed list.
           visited.push_back( currSquare );
           openList.pop();
           
           if ( (currSquare->get_box().x == endTile->get_box().x) && (currSquare->get_box().y == endTile->get_box().y) )
           
           //get adjacent squares
           Tile adjacentSquares[] = { tiles[ index_of_tile( ( currSquare->get_box().x / TILE_WIDTH ) - 1, ( currSquare->get_box().y / TILE_HEIGHT ) - 1) ],      //top left
                                       tiles[ index_of_tile( ( currSquare->get_box().x / TILE_WIDTH ) - 1, ( currSquare->get_box().y / TILE_HEIGHT ) ) ],         //left
                                       tiles[ index_of_tile( ( currSquare->get_box().x / TILE_WIDTH ) - 1, ( currSquare->get_box().y / TILE_HEIGHT ) + 1 ) ],     //bottom left 
                                       tiles[ index_of_tile( ( currSquare->get_box().x / TILE_WIDTH ), ( currSquare->get_box().y / TILE_HEIGHT ) - 1 )],          //top
                                       tiles[ index_of_tile( ( currSquare->get_box().x / TILE_WIDTH ), ( currSquare->get_box().y / TILE_HEIGHT ) + 1 ) ],         //bottom
                                       tiles[ index_of_tile( ( currSquare->get_box().x / TILE_WIDTH ) + 1, ( currSquare->get_box().y / TILE_HEIGHT ) - 1 ) ],     //top right
                                       tiles[ index_of_tile( ( currSquare->get_box().x / TILE_WIDTH ) + 1, ( currSquare->get_box().y / TILE_HEIGHT ) ) ],         //right
                                       tiles[ index_of_tile( ( currSquare->get_box().x / TILE_WIDTH ) + 1, ( currSquare->get_box().y / TILE_HEIGHT ) + 1 ) ],  }; //bottom right
           
           //for each of the 8 squares adjacent to this currentSquare
           for ( int i = 0; i < 8; ++i )
           {
               //if impassable, ignore
               if ( adjacentSquares[i]->get_type() < 5 && !is_in_closed_list( adjacentSquares[i], visited) )
               {
                    //adjacentSquares[i]->;
                    //if not in openList, add.
                    if ( !is_in_open_list( *adjacentSquares[i], openList ) )
                    {
                        openList.push( *adjacentSquares[i] );
                    }
               }
           }
     }
     
     /*int action = 0;
     
     if (bumped)
     {
         while(action==lastAction)
         {
             action = (rand() % 5);                                          
         }         
     }
     else
     {
         if (lastAction==0)
         {
             action = (rand() % 5);                                                                      
         }
     }
     
     switch(action)
     {
         case 0:
              xVel = 0;
              yVel = 0;
              break;
         case 1: 
              xVel = 0;
              yVel -= PLAYER_HEIGHT / 2; 
              break;
         case 2: 
              xVel = 0;
              yVel += PLAYER_HEIGHT / 2; 
              break;
         case 3: 
              xVel -= PLAYER_WIDTH / 2; 
              yVel = 0;
              break;
         case 4: 
              xVel += PLAYER_WIDTH / 2; 
              yVel = 0;
              break;
     }
     
     lastAction = action;*/

void Enemy::move( Tile *tiles[] )
{
    bumped = false;
    //Move the player left or right
    box.x += xVel;

    //If the player went too far to the left or right or touched a wall
    if( ( box.x < 0 ) || ( box.x + PLAYER_WIDTH > LEVEL_WIDTH ) || touches_wall( box, tiles ) )
    {
        //move back
        box.x -= xVel;
        bumped = true;
    }

    //Move the player up or down
    box.y += yVel;

    //If the player went too far up or down or touched a wall
    if( ( box.y < 0 ) || ( box.y + PLAYER_HEIGHT > LEVEL_HEIGHT ) || touches_wall( box, tiles ) )
    {
        //move back
        box.y -= yVel;
        bumped = true;
    }
}

void Enemy::show()
{
    //Show the enemy
    //If Foo is moving left
    if( xVel < 0 )
    {
        //Set the animation to left
        status = PLAYER_LEFT;

        //Move to the next frame in the animation
        frame++;
    }
    //If Foo is moving right
    else if( xVel > 0 )
    {
        //Set the animation to right
        status = PLAYER_RIGHT;

        //Move to the next frame in the animation
        frame++;
    }
    else if( yVel > 0 )
    {
        //Set the animation to right
        status = PLAYER_DOWN;

        //Move to the next frame in the animation
        frame++;
    }
    else if( yVel < 0 )
    {
        //Set the animation to right
        status = PLAYER_UP;

        //Move to the next frame in the animation
        frame++;
    }
    //If Foo standing
    else
    {
        //Restart the animation
        frame = 0;
    }

    //Loop the animation
    if( frame >= 3 )
    {
        frame = 0;
    }

    //SDL_SetAlpha( player, 0x00, 0 );
    //Show the stick figure
    if( status == PLAYER_RIGHT )
    {
        apply_surface( box.x - camera.x, box.y - camera.y, enemy, screen, &clipsRight[ frame ], 0 );
    }
    else if( status == PLAYER_LEFT )
    {
        apply_surface( box.x - camera.x, box.y - camera.y, enemy, screen, &clipsLeft[ frame ], 0 );
    }
    else if( status == PLAYER_UP )
    {
        apply_surface( box.x - camera.x, box.y - camera.y, enemy, screen, &clipsUp[ frame ], 0 );
    }
    else if( status == PLAYER_DOWN )
    {
        apply_surface( box.x - camera.x, box.y - camera.y, enemy, screen, &clipsDown[ frame ], 0 );
    }
}

SDL_Rect Enemy::getBox()
{
   return box;
}

//===============================================
//helper functions for computing the optimum path
//===============================================

// 1. index_of_tile
//    - returns the index of the tile from the 1D array of Tiles given a 
//      row and col number representation of a 2D version of it
int index_of_tile( int row, int col )
{
    return ((LEVEL_WIDTH / TILE_WIDTH) * row) + col;
}

// 2. index_of_tileXY
//    - adapter method for index_of_tile, where it will take in x and y coord
//      instead of row and col indices
int index_of_tileXY( int x, int y )
{
    return index_of_tile(( x / TILE_WIDTH ), ( y / TILE_HEIGHT ));
}    

bool is_in_closed_list( Tile &t,  vector<Tile*> tpq )
{
     if ( tpq.empty() )
        return false;
        
     for (int i = 0; i < tpq.size(); ++i)
     {
         if ( (tpq[i]->get_box().x == t.get_box().x) && (tpq[i]->get_box().y == t.get_box().y) )
            return true;
     }
     
     return false;
}

/*bool is_in_open_list( Tile &t, queue<Tile*> tpq )
{
     if (tpq.empty())
        return false;
     
     priority_queue<Tile> tempQueue = tpq;
     vector<Tile> tempVector;
     
     
     while (!tempQueue.empty())
     {
         tempVector.push_back( tempQueue.top() );
         tempQueue.pop();
     }
     
     for (int i = 0; i < tempVector.size(); ++i)
     {
         if ( (tempVector[i].get_box().x == t.get_box().x) && (tempVector[i].get_box().y == t.get_box().y) )
            return true;
     }
     
     return false;
}

// 3. compute_h
//    - computes the heuristic
int compute_h( int start_x, int start_y, int goal_x, int goal_y )
{
    return abs( start_x - goal_x ) + abs ( start_y - goal_y );
}

// 4. bool operator<
//    - overloads the < sign for use with the Tiles and the priority queue
bool operator<( const Tile &t1, const Tile &t2 )
{
     return t1.f_val < t2.f_val;
}*/
